#include "EntryItem.h"
#include "xMappingNode.h"
#include "NodeOutPort.h"
#include "NodeManager.h"
#include "UnfoldButton.h"
#include "EntryFrameItem.h"
#include "VariablePanel.h"
#include "GraphicsButton.h"
#include <QPixmap>
#include <QPainter>
#include <QPen>
#include <QBrush>
#include <QtGui/QGraphicsSceneContextMenuEvent>
#include "xNodeType_WOP.h"


using namespace std;

EntryItem::EntryItem(string entryName, string entryType, xMappingNode* entryNode, WOP_Entry* wopEntry, AbstractManager* manager,VariablePanel* panel,EntryFrameItem* entryFrame)
	:PanelTreeItem( entryName, manager , panel)
{
	this->_type = entryType;
	this->_mpnNode  = entryNode;
	this->_wopEntry = wopEntry;
	this->_isUnfold = false;

	this->_nodeType = AbstractShapeItem::ENTRY_NODE;
	this->_mpnNode->setForeachElements((_manager->isInForEachRect(this)));
	if (entryFrame!=NULL){
		this->setParent(entryFrame);
	} 

	//如果是ref type，而且wop val不是null，新增展開的icon
	if( this->_type == "object" || this->_type == "array" || ( this->_type == "ref" && ( this->_wopEntry->getVal() != "null" && this->_wopEntry->getVal() != "0x0" ) ) ) {
		this->initUnfoldButton();
	}
	this->setupPort();
}


EntryItem::~EntryItem(void)
{
}

void EntryItem::setupPort()
{
	for(int i = 0; i< _mpnNode->getOutportSize(); ++i){
		xOutMappingPort* omp = _mpnNode->getOutPort(i);
		_outportList.push_back(new NodeOutPort(omp,this));
	}

	_outportList.at(0)->setX(this->_width - NodePort::RADIUS);
	_outportList.at(0)->setY(HEIGHT / 2 - NodePort::RADIUS + 1);
}

WOP_Entry* EntryItem::getWOPEntry()
{
	return this->_wopEntry;
}

void EntryItem::remove()
{
	assert(false);
}

void EntryItem::removeAllLinks()
{
	std::vector<NodeOutPort*> outPorts = this->getOutportList();
	std::vector<NodeOutPort*>::iterator itr;
	for ( itr = outPorts.begin(); itr != outPorts.end(); ++itr )
	{
		(*itr)->removeAllLinks();
	}
}

void EntryItem::unfold( bool isUnfold )
{
	NodeManager* manager = dynamic_cast<NodeManager*>(_manager);
	if ( isUnfold == true ){
		if ( _children.size() == 0){
			// 當使用者按下unfold按鈕時再建立unfold出來的items
			_children = manager->createUnfoldEntries(this->_wopEntry);

			// 設定unfold items的parent，再將items加入panel中
			std::vector<EntryItem*>::iterator itr;
			int index = _panel->indexOfItem(this) + 1;
			for ( itr = _children.begin(); itr != _children.end(); ++itr )
			{
				(*itr)->setParent(this);
				this->getMappingNode()->addUnfoldChild((*itr)->getMappingNode());
				_panel->insertItem(*itr, index);
				index++;
			}
		} 
		// 如果已經unfold過，直接set visible
		else {
			setChildrenVisible(true);
		}

	} 
	else if ( isUnfold == false ){
		setChildrenVisible(false);
	}
	_panel->updateItemsPosition();
}

void EntryItem::contextMenuEvent( QGraphicsSceneContextMenuEvent * event ) {
	if( !this->_unfoldButton || !this->_unfoldButton->isVisible() ) {
		return;
	}

	event->accept();

	xNodeType_WOP * wopNode = dynamic_cast< xNodeType_WOP * >( this->_mpnNode->getNodeTypePtr() );
	assert( wopNode || !"invalid node type" );
	emit this->contextMenuRequired( this );
}

void EntryItem::drawType( QPainter * painter )
{
	std::string type = this->_type;
	if( type == "object" || type == "ref" ) {
		type += " " + this->_wopEntry->getVarType();
	}

	QFont sansFont("Helvetica", 8);
	QFontMetrics fontMetrics(sansFont);
	int typeBlockWidth = fontMetrics.width(type.c_str()) + TYPE_BLOCK_LEFT_PADDING + TYPE_BLOCK_RIGHT_PADDING;
	int typeBlockHeight = fontMetrics.height();

	painter->setBrush(QBrush(QColor("#575757")));
	painter->drawRoundedRect( LEFT_PADDING*getlevel() , TOP_PADDING, typeBlockWidth, typeBlockHeight, 2 ,2);

	painter->setPen(QPen(QColor("#FFFFFF")));
	painter->setFont(sansFont);
	painter->drawText( LEFT_PADDING*getlevel(), TOP_PADDING, typeBlockWidth, typeBlockHeight, Qt::AlignCenter, trf(type).c_str());

	// draw spliter
	painter->setPen( QColor( "gray" ) );
	painter->drawLine( 154, 0, 154, HEIGHT );

	// draw wop value
	painter->setPen( this->_fontColor->color() );
	sansFont.setBold( true );
	sansFont.setPointSize( 9 );
	painter->setFont(sansFont);
	painter->drawText( 154 + RIGHT_PADDING, TOP_PADDING, 100, HEIGHT, Qt::AlignLeft, this->_wopEntry->getVal().c_str() );
}
